﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace PixelWarfare
{
    /// <summary>
    /// Class to represent the main menu screen.
    /// </summary>
    class MainMenuScreen : Menu
    {
        #region Fields

        private static MainMenuScreen theOne;       // Singleton instance.

        private int players;                        // Number of players set to active.
        private Game game;

        #endregion

        #region Constructors

        /// <summary>
        /// Creates the main menu and adds all the necessary items with there delegates.
        /// </summary>
        private MainMenuScreen()
            : base()
        {
            game = Game.GetInstance();

            // All players start off set to active.
            players = 4;

            // Add all the items to the screen.

            // Start points for all the letters has to be hard coded.
            Point[] points = new Point[] { new Point(23, 27), new Point(58, 27), new Point(90, 36), new Point(129, 28), new Point(168, 27) };

            this.AddBlobItem(new Bitmap(GetType(), "img.Start.jpg"), /*125*/250, 400, points, 15, new OnClick(StartGame));

            // Rules page hasn't been implemented yet.
            /*
            points = new Point[] { new Point(19, 28), new Point(63, 48), new Point(91, 32), new Point(127, 27), new Point(173, 27) };

            this.AddBlobItem(new Bitmap(GetType(), "img.Rules.jpg"), 375, 400, points, 15, new OnClick(StartGame));
             */

            this.AddOptionItem("RED", new string[] { "HUMAN", "OFF" }, 125, 75,
                new Font("Arial", 20), Color.Red, Color.DarkRed, new OnClick(SwitchRedActivity));

            this.AddOptionItem("BLUE", new string[] { "HUMAN", "OFF" }, 125, 150,
                new Font("Arial", 20), Color.Blue, Color.MediumBlue, new OnClick(SwitchBlueActivity));

            this.AddOptionItem("PURPLE", new string[] { "HUMAN", "OFF" }, 125, 225,
                new Font("Arial", 20), Color.FromArgb(255, 0, 255), Color.Purple, new OnClick(SwitchPurpleActivity));

            this.AddOptionItem("GREEN", new string[] { "HUMAN", "OFF" }, 125, 300,
                new Font("Arial", 20), Color.FromArgb(0, 255, 0), Color.Green, new OnClick(SwitchGreenActivity));

            this.AddOptionItem("MAP", new string[] { "CHOSEN", "RANDOM" }, 375, 75,
                new Font("Arial", 20), Color.Yellow, Color.FromArgb(128, 128, 0), new OnClick(ToggleMapSelection));

            this.AddOptionItem("SCORING", new string[] { "POINTS", "WINS" }, 375, 150,
                new Font("Arial", 20), Color.Yellow, Color.FromArgb(128, 128, 0), new OnClick(ToggleScoring));
            
            // Need to add the ability to hide menu items.
            /*
            this.AddOptionItem("GOAL", new string[] { "1000 points", "1500 points" }, 375, 225,
               new Font("Arial", 20), Color.Yellow, Color.FromArgb(128, 128, 0), new OnClick(ToggleScoring));

            this.AddOptionItem("GOAL", new string[] { "3 wins", "5 wins" }, 375, 225,
               new Font("Arial", 20), Color.Yellow, Color.FromArgb(128, 128, 0), new OnClick(ToggleScoring));
             */
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Gets the singleton instance of the class.
        /// </summary>
        /// <returns>Return the singleton instance.</returns>
        public static MainMenuScreen GetInstance()
        {
            if (theOne == null)
            {
                theOne = new MainMenuScreen();
            }

            /* Since were using it as a singleton we need to update it
             * as unexpired everytime we want to show it again. 
             */
            theOne.ValidateScreen();

            return theOne;
        }

        /// <summary>
        /// Draws all the items on the screen by calling base.Draw().
        /// Then if you have less then two players currently active
        /// give a message to the user that he needs atleast two players.
        /// </summary>
        /// <param name="g"></param>
        public override void Draw(Graphics g)
        {
            // Draws all the items that were added in the constructor.
            base.Draw(g);

            if (players < 2)
            {
                Utility.DrawTextCentered(g, "MUST HAVE ATLEAST TWO PLAYERS", Color.Yellow, 225, 0, 15);
            }
        }

        /// <summary>
        /// Do the events associated with each key.
        /// </summary>
        /// <param name="key">The key that was pressed.</param>
        public override void KeyPress(Keys key)
        {
            switch (key)
            {
                case Keys.Enter:
                    StartGame();
                    break;
                case Keys.Escape:
                    Application.Exit();
                    break;
            }
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Sets up the variables for the game based on which
        /// players were selected, and lets the control know 
        /// that we need to switch to the next screen.
        /// </summary>
        private void StartGame()
        {
            // Dont do anything unless we have enough players.
            if (players >= 2)
            {

                game.ResetScores();
                game.InitGameVariables();

                if (Game.RandomMap)
                {
                    Map.ResetRandom();
                    Game.GetInstance().SetMap(Map.NextRandom());
                    InvalidateScreen(BlobSelectionScreen.GetInstance());
                }
                else
                {
                    InvalidateScreen(MapSelectionScreen.GetInstance());
                }
            }
        }

        /// <summary>
        /// Toggles map selection on and off when you click the button.
        /// </summary>
        private void ToggleMapSelection()
        {
            Game.RandomMap = !Game.RandomMap;
        }

        /// <summary>
        /// Toggles scoring when you click the button.
        /// </summary>
        private void ToggleScoring()
        {
            if (Game.ScoringType == Game.ByPoints)
            {
                Game.ScoringType = Game.ByWins;
            }
            else
            {
                Game.ScoringType = Game.ByPoints;
            }
        }

        /* The next four methods are actived whenever one of the player items is
         * selected, each one toggles the activity of the given player and keeps
         * track of the total. 
         */

        private void SwitchRedActivity()
        {
            game.SetActivity(0, !game.GetActivity(0));

            if (game.GetActivity(0))
            {
                players++;
            }
            else
            {
                players--;
            }
        }

        private void SwitchBlueActivity()
        {
            game.SetActivity(1, !game.GetActivity(1));
            
            if(game.GetActivity(1))
            {
                players++;
            }
            else
            {
                players--;
            }
        }

        private void SwitchPurpleActivity()
        {
            game.SetActivity(2, !game.GetActivity(2));

            if (game.GetActivity(2))
            {
                players++;
            }
            else
            {
                players--;
            }
        }

        private void SwitchGreenActivity()
        {
            game.SetActivity(3, !game.GetActivity(3));

            if (game.GetActivity(3))
            {
                players++;
            }
            else
            {
                players--;
            }
        }

        #endregion
    }
}
